<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /**
     * Symbol 数据类型：
     *      该数据类型具有唯一性（Symbol实际上是一个变量），
     *      不能遍历和运算
     *      但可以通过for('Symbol标识符')来获取Symbol
     * Symbol创建方式：
     *  1.Symbol()
     *  2.Symbol('Symbol 的标识符')
     * Symbol应用：
     * 1.可以向对象中添加具有唯一性的方法
     */
    let s1 = Symbol()
    console.log(s1, typeof s1)
    let s2 = Symbol('Jackson')
    let s3 = Symbol('Jackson')
    console.log(s2 === s3)

    const Jack = {
        name: "Jason",
        up() {
            console.log("Jack up")
        },
        down() {
            console.log("Jack down")
        }
    }

    // region 方式一
    const method = {
        up: Symbol("up"),
        down: Symbol("down")
    }

    Jack[method.up] = () => {
        console.log("method.up")
    }
    Jack[method.down] = () => {
        console.log("method.down")
    }

    console.log(Jack)
    // endregion

    // region 方式二
    const Black = {
        name: "Black",
        //属性名是变量名时使用[]
        [Symbol("up")]: function () {
            console.log("Symbol Black up")
        },
        //属性名是变量名时使用[]
        [Symbol("down")]: function () {
            console.log("Symbol Black down")
        }
    }
    console.log(Black)
    // endregion

    // region  Symbol API演示
    const arr1 = ['jack', 'black', 'Jason']
    const arr2 = ['Mike', 'Black']
    console.log(arr1.concat(arr2))
    // isConcatSpreadable表示数组合并时是否可以展开
    arr2[Symbol.isConcatSpreadable] = false
    console.log(arr1.concat(arr2))
    // endregion

    // region   Symbol迭代器的使用
    console.log("Symbol迭代器")
    const names = ["Jackson", "Black", "Jason", "Jack"]
    for (const name of names) {
        console.log(name)
    }

    // endregion

    // region Symbol自定义遍历
    const class_ = {
        name: [...names],
        [Symbol.iterator]() {
            let index = 0
            let _this = this
            let result;
            return {
                next: function () {
                    if (index < _this.name.length) {
                        result = {value: _this.name[index], done: false}
                        index++;
                        return result;
                    } else {
                        return {value: undefined, done: true}
                    }
                }
            }
        }
    }
    console.log("自定义迭代器")
    for (let class1 of class_) {
        console.log(class1)
    }
    // endregion
</script>
</body>
</html>